<template>
  <div className="demo-title">
    <h1>标注图层-北京充电桩分布</h1>
    <h3>使用Loca数据源展示海量点标注</h3>
  </div>
  <div id="map"></div>
</template>

<script>
export default {
  name: 'ChargeLoca',
  data() {
    return {
      map: null,
      loca: null,
      labelsLayer: null,
      normalMarker: null,
    };
  },
  async mounted() {
    // 确保 DOM 元素已经渲染，并且 #map 已经存在
    await this.$nextTick(); // 等待Vue更新DOM

    // 1. 动态加载高德地图SDK和Loca SDK
    // 确保这两个脚本加载完成后，window.AMap 和 window.Loca 才能被访问
    try {
      await this.loadScript('https://webapi.amap.com/maps?v=2.0&key=19b72c7d05dfe5b3a710221d39eb2e51');
      await this.loadScript('https://webapi.amap.com/loca?v=2.0.0&key=19b72c7d05dfe5b3a710221d39eb2e51');

      // 检查 AMap 和 Loca 是否已全局可用
      if (!window.AMap || !window.Loca) {
        console.error("AMap or Loca SDK failed to load or are not globally available.");
        return; // 如果未加载成功，则停止执行
      }

      // 2. 初始化 AMap
      this.map = new window.AMap.Map('map', { // 使用 window.AMap 明确引用全局对象
        zoom: 13.12,
        showLabel: false,
        viewMode: '3D',
        center: [120.353950,30.314408],
        mapStyle: 'amap://styles/28f5f1e7774710f2d218ab9ba738b444',
      });

      // 3. 初始化 Loca
      this.loca = new window.Loca.Container({ // 使用 window.Loca 明确引用全局对象
        map: this.map,
      });

      // 4. 初始化 LabelsLayer
      this.labelsLayer = new window.Loca.LabelsLayer({ // 使用 window.Loca 明确引用全局对象
        zooms: [10, 20],
      });

      // 5. 设置 GeoJSON source
      const geo = new window.Loca.GeoJSONSource({ // 使用 window.Loca 明确引用全局对象
        data: {
          "type": "FeatureCollection",
          "features": [
            {
              "type": "Feature",
              "properties": {
                "name": "尚+大楼电动车充电桩",
                "address": "浙江省杭州市钱塘区白杨街道学林街927号浙江理工大学(下沙校区)"
              },
              "geometry": {
                "type": "Point",
                "coordinates": [120.349923, 30.315646]
              }
            },
            {
              "type": "Feature",
              "properties": {
                "name": "25号楼电动车充电桩",
                "address": "浙江省杭州市钱塘区白杨街道学林街927号浙江理工大学(下沙校区)"
              },
              "geometry": {
                "type": "Point",
                "coordinates": [120.353359, 30.315104]
              }
            },
            {
              "type": "Feature",
              "properties": {
                "name": "生活区3号楼电动车1号充电桩",
                "address": "浙江省杭州市钱塘区白杨街道学源街67号浙江理工大学下沙校区生活二区"
              },
              "geometry": {
                "type": "Point",
                "coordinates": [120.364496, 30.316514]
              }
            },
            {
              "type": "Feature",
              "properties": {
                "name": "生活区3号楼电动车2号充电桩",
                "address": "浙江省杭州市钱塘区白杨街道学源街67号浙江理工大学下沙校区生活二区"
              },
              "geometry": {
                "type": "Point",
                "coordinates": [120.364151, 30.316736]
              }
            },
            {
              "type": "Feature",
              "properties": {
                "name": "生活区3号楼电动车3号充电桩",
                "address": "浙江省杭州市钱塘区白杨街道学源街67号浙江理工大学下沙校区生活二区"
              },
              "geometry": {
                "type": "Point",
                "coordinates": [120.363460, 30.316729]
              }
            },
            {
              "type": "Feature",
              "properties": {
                "name": "生活区9号楼电动车充电桩",
                "address": "浙江省杭州市钱塘区白杨街道学源街67号浙江理工大学下沙校区生活二区"
              },
              "geometry": {
                "type": "Point",
                "coordinates": [120.362819, 30.316736]
              }
            },
            {
              "type": "Feature",
              "properties": {
                "name": "生活区4号楼电动车充电桩",
                "address": "浙江省杭州市钱塘区白杨街道学源街67号浙江理工大学下沙校区生活二区"
              },
              "geometry": {
                "type": "Point",
                "coordinates": [120.362119, 30.316660]
              }
            },
          ]
        }
        // url: 'https://gitee.com/cao-jia-ming/campus-management/raw/master/charging_pile.json',
      });
      this.labelsLayer.setSource(geo);

      // 6. 设置 style for labels
      this.labelsLayer.setStyle({
        icon: {
          type: 'image',
          image: 'https://a.amap.com/Loca/static/loca-v2/demos/mock_data/charging_pile.png',
          size: [40, 60],
          anchor: 'center',
        },
        text: {
          content: (index, feat) => {
            return feat.properties.name;
          },
          style: {
            fontSize: 16,
            fontWeight: 'normal',
            fillColor: '#5CDE8E',
            strokeColor: '#000',
            strokeWidth: 2,
          },
          direction: 'bottom',
        },
        extData: (index, feat) => {
          return feat.properties;
        },
      });

      // 7. Add labels layer to Loca
      this.loca.add(this.labelsLayer);

      // 8. Handle complete event
      this.labelsLayer.on('complete', () => {
        this.normalMarker = new window.AMap.Marker({ // 使用 window.AMap 明确引用全局对象
          offset: [70, -15],
        });
        const labelMarkers = this.labelsLayer.getLabelsLayer().getAllOverlays();
        for (let marker of labelMarkers) {
          marker.on('mouseover', (e) => {
            const position = e.data.data && e.data.data.position;
            if (position) {
              this.normalMarker.setContent(
                  '<div class="amap-info-window">地址：' + marker.getExtData().address + '</div>',
              );
              this.normalMarker.setPosition(position);
              this.map.add(this.normalMarker);
            }
          });
          marker.on('mouseout', () => {
            this.map.remove(this.normalMarker);
          });
        }
      });

    } catch (error) {
      console.error("Error loading AMap/Loca SDK or initializing map:", error);
    }
  },
  methods: {
    loadScript(url) {
      return new Promise((resolve, reject) => {
        // 检查脚本是否已经存在，避免重复加载
        if (document.querySelector(`script[src="${url}"]`)) {
          resolve();
          return;
        }
        const script = document.createElement('script');
        script.src = url;
        script.onload = () => resolve();
        script.onerror = () => reject(new Error(`Failed to load script: ${url}`));
        document.head.appendChild(script);
      });
    },
  },
  beforeUnmount() {
    // Clean up map instance
    if (this.map) {
      this.map.destroy();
      this.map = null; // 置为 null 帮助 GC
    }
    if (this.loca) {
      this.loca.destroy(); // Loca 也有 destroy 方法
      this.loca = null;
    }
  },
}
</script>

<style>
/* 确保 #map 有明确的尺寸 */
html,
body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden; /* 避免滚动条 */
}

#map {
  width: 100%;
  height: calc(100vh - 100px); /* 示例：视口高度减去顶部标题的高度 */
  /* 或者如果父元素不是视口高度，就直接 height: 100%; 但要确保父元素有高度 */
  margin: 0;
  padding: 0;
  position: absolute; /* 使其脱离文档流，不影响标题位置 */
  top: 0;
  left: 0;
  z-index: 0; /* 确保地图在标题下方 */
}

.demo-title {
  position: absolute;
  top: 50px;
  left: 50px;
  z-index: 10; /* 确保标题在地图上方 */
  background-color: rgba(255, 255, 255, 0.8); /* 增加背景，使其可见 */
  padding: 10px 20px;
  border-radius: 5px;
}

.amap-info-window {
  width: 150px;
  background: #fff;
  border-radius: 3px;
  padding: 3px 7px;
  box-shadow: 0 2px 6px 0 rgba(114, 124, 245, .5);
  position: relative;
  font-size: 12px;
}

h1 {
  margin: 0;
  color: #ACB3BB;
}

h3 {
  font-weight: normal;
  margin-top: 5px;
  color: #8E939D;
}
</style>